# 2023年秋季学期《高等程序设计语言》期末考核项目：学生信息管理系统

import re
import os
import os.path

# 导入必需模块

# 将工作目录设置为当前运行代码的目录
os.chdir(os.path.dirname(os.path.abspath(__file__)))

# 在工作目录内创建新文件夹“newdir”，创建前事先判断“newdir”文件夹是否已存在
if not os.path.exists("newdir"):
    os.mkdir("newdir")

# 重新设定新创建的文件夹newdir为工作目录
os.chdir("newdir")


# 编写目录子函数
def menm():
    # 展示页面
    print("\n\n", "学生信息管理系统".center(60, "="), "\n\n")
    print("目录".center(60), "\n")
    print("\t\t\t1. 录入学生信息")
    print("\t\t\t2. 查找学生信息")
    print("\t\t\t3. 删除学生信息")
    print("\t\t\t4. 修改学生信息")
    print("\t\t\t5. 排序")
    print("\t\t\t6. 统计学生人数")
    print("\t\t\t7. 显示所有学生信息")
    print("\t\t\t8. 打开学生信息文件")
    print("\t\t\t9. 退出系统")
    print(
        "=====================================================================", "\n\n"
    )


# 编写主函数
def main():
    # 在工作目录(D:\\newdir)下创建学生信息文本文件stuinfomgr.txt，创建前事先判断“stuinfomgr.txt”文件是否已存在
    if not os.path.exists("stuinfomgr.txt"):
        with open("stuinfomgr.txt", "w+", encoding="UTF-8") as fp:
            # 以“学号  姓名  性别  数学  物理  Python  平均成绩”作为stuinfomgr.txt文本表头写入文件，并用转义字符调整各个文字位置及换行
            fp.write(
                "学号\t\t姓名\t\t性别\t\t数学\t\t物理\t\tPython\t\t平均成绩\n------------------------------------------------------------------------------------"
            )

    # 功能模块
    while True:
        menm()  # 调用目录
        select = int(input("\n请选择功能:"))  # 目录选择

        # 功能模块1：录入学生信息，将信息写入学生信息文本文件stuinfomgr.txt
        if select == 1:
            # 用input提示待录入的信息“学号、姓名、性别、数学成绩、物理成绩、Python成绩”，并将录入的信息写入学生信息文件stuinfomgr.txt
            # 根据“数学成绩、物理成绩、Python成绩”三科成绩计算平均成绩并写入学生信息文件stuinfomgr.txt
            while True:
                stu_id = input("\n请输入学生学号:")
                stu_name = input("\n请输入学生姓名:")
                stu_gender = input("\n请输入学生性别:")
                stu_score_math = int(input("请输入数学成绩:"))
                stu_score_phy = int(input("请输入物理成绩:"))
                stu_score_pyth = int(input("请输入Python成绩:"))
                stu_ave = round((stu_score_math + stu_score_phy + stu_score_pyth) / 3,2)

                with open("stuinfomgr.txt", "a+", encoding="UTF-8") as fp:
                    fp.writelines(
                        [
                            "\n",
                            stu_id,
                            "\t\t",
                            stu_name,
                            "\t\t",
                            stu_gender,
                            "\t\t",
                            str(stu_score_math),
                            "\t\t",
                            str(stu_score_phy),
                            "\t\t",
                            str(stu_score_pyth),
                            "\t\t",
                            str(stu_ave),
                        ]
                    )

                selec = input("\n是否继续输入学生信息? y/n:")
                if selec != "y":
                    break
        # 功能模块2：按学号或姓名在学生信息文件stuinfomgr.txt中查找学生信息，并print查找到的信息
        elif select == 2:
            while True:
                # 读取学生信息文件stuinfomgr.txt中的信息，并按“学号”或“姓名”查找指定学生
                # 将查找到的学生的所有信息“学号、姓名、性别、数学成绩、物理成绩、Python成绩、平均成绩”用print输出
                # 如果输入的“学号”或“姓名”不存在，用print反馈“未查到该学生信息”
                char = input("\n请输入待查询的学生的学号或姓名:")
                with open("stuinfomgr.txt", "r", encoding="UTF-8") as fp:
                    lst = fp.readlines()

                for item in lst:
                    if char in item[:9]:
                        lst_info = item.split(sep="\t\t")
                        print(
                            "\n姓名:",
                            lst_info[1],
                            "\t学号:",
                            lst_info[0],
                            "\t性别:",
                            lst_info[2],
                        )
                        print("数学成绩：", lst_info[3], end="\t")
                        print("物理成绩：", lst_info[4], end="\t")
                        print("Python成绩:", lst_info[5])
                        print("平均成绩：", lst_info[6], "\n")
                        break
                else:
                    print("未查到学生信息")
                # 询问是否继续查找学生信息
                selec = input("是否继续查找学生信息? y/n:")
                if selec != "y":
                    break

        # 功能模块3：按学号或姓名删除学生信息文件stuinfomgr.txt中的学生信息
        elif select == 3:
            while True:
                char = input("\n请输入待删除的学生学号或姓名:")
                with open("stuinfomgr.txt", "r", encoding="UTF-8") as fp:
                    lst = fp.readlines()

                k = 0
                for item in lst[2:]:
                    if char in item:
                        break
                    k += 1
                else:
                    print("未查到学生信息")
                    break
                # 读取学生信息文件stuinfomgr.txt中的信息，并按“学号”或“姓名”查找指定学生，删除stuinfomgr.txt文件中该学生的所有信息
                # 文件中的其它信息保持不变
                # lst[k : k + 1] = []
                del lst[k + 2]

                with open("stuinfomgr.txt", "w", encoding="UTF-8") as fp:
                    fp.writelines(lst)
                # 询问是否继续删除学生信息
                selec = input("是否继续删除学生信息? y/n")
                if selec != "y":
                    break

        # 功能模块4：按学号或姓名查找学生信息文件stuinfomgr.txt中指定学生，并按关键字“学号、姓名、性别、数学成绩、物理成绩、Python成绩”6个关键字修改该名学生在stuinfomgr.txt文件中的指定信息
        elif select == 4:
            while True:
                # 读取学生信息文件stuinfomgr.txt中所有信息
                with open("stuinfomgr.txt", "r", encoding="UTF-8") as fp:
                    lst = fp.readlines()
                # 按学号或姓名查找读取到的信息中的指定学生
                lst_of_dic = []
                # print(lst)
                if len(lst) >= 2:
                    for item in lst[2:]:
                        elem = item.split(sep="\t\t")
                        dic = {
                            "学号": elem[0],
                            "姓名": elem[1],
                            "性别": elem[2],
                            "数学": elem[3],
                            "物理": elem[4],
                            "Python": elem[5],
                        }
                        lst_of_dic.append(dic)
                else:
                    print("无学生信息,请先录入\n\n")
                    break
                # 对学生信息字典进行操作，按指定关键字修改该学生对应关键字的信息
                k = 0
                char = input("\n请输入待修改的学生学号或姓名:")
                for item in lst_of_dic:
                    if char == item["姓名"] or char == item["学号"]:
                        break
                    k += 1
                else:
                    print("未查到学生信息")
                    break

                while True:
                    scro = input("\n请输入待修改的项(学号/姓名/性别/数学/物理/Python):")
                    if scro in "请输入待修改的项(学号/姓名/性别/数学/物理/Python)":
                        val = input("\n请输入修改后的内容:")
                        lst_of_dic[k][scro] = val
                    else:
                        print("关键字不存在")
                        break
                # 将修改后的学生信息写入学生信息文件stuinfomgr.txt，并保持文件内其他学生的信息不变
                # 修改行
                stu_ave = (
                    int(lst_of_dic[k]["数学"])
                    + int(lst_of_dic[k]["物理"])
                    + int(lst_of_dic[k]["Python"])
                ) / 3
                lst_ch = "".join(
                    [
                        lst_of_dic[k]["学号"],
                        "\t\t",
                        lst_of_dic[k]["姓名"],
                        "\t\t",
                        lst_of_dic[k]["性别"],
                        "\t\t",
                        str(lst_of_dic[k]["数学"]),
                        "\t\t",
                        str(lst_of_dic[k]["物理"]),
                        "\t\t",
                        str(lst_of_dic[k]["Python"]),
                        "\t\t",
                        str(stu_ave),
                        "\n",
                    ]
                )

                lst[k + 2] = lst_ch

                # 将修改后的内容写进新文件
                with open("stuinfomgr.txt", "w", encoding="UTF-8") as fp:
                    fp.writelines(lst)
                # 询问是否继续修改其他学生信息
                selec = input("是否继续修改下一个学生的信息? y/n:")
                if selec != "y":
                    break

        #  功能模块5：将学生信息文件stuinfomgr.txt中所有学生信息按关键字进行排序
        elif select == 5:
            # 读取学生信息文件stuinfomgr.txt中所有信息，采用格式化字符串的方法将单个学生信息存储为字典
            with open("stuinfomgr.txt", encoding="UTF-8") as fp:
                lst = fp.readlines()

            # 生成元素为字典的列表，列表中每一元素都是一个学生的字典
            lst_of_dic = []
            if len(lst) >= 2:
                for item in lst[2:]:
                    elem = item.split(sep="\t\t")
                    # print(elem)
                    av = elem[6].split(sep="\n")[0]
                    dic = {
                        "学号": elem[0],
                        "姓名": elem[1],
                        "性别": elem[2],
                        "数学": elem[3],
                        "物理": elem[4],
                        "Python": elem[5],
                        "平均成绩": str(av),
                    }
                    lst_of_dic.append(dic)
            else:
                print("无学生信息,请先录入\n\n")
                break

            # 对所有学生信息的字典按照“学号”、“数学成绩”、“物理成绩”、“Python成绩”或“平均成绩”5个关键字进行排序
            choice = input("请输入排序名目(学号/数学/物理/Python/平均分):")
            if choice in "学号/数学/物理/Python/平均分":
                sen_or_desen = input("请输入按升序排序还是降序排序(升/降):")
                # 将排好序的学生信息字典写入到学生信息文件stuinfomgr.txt中
                if sen_or_desen == "升":
                    for item1 in range(len(lst_of_dic) - 1):
                        for item2 in range(item1, len(lst_of_dic)):
                            if int(lst_of_dic[item1][choice]) >= int(
                                lst_of_dic[item2][choice]
                            ):
                                lst_of_dic[item1], lst_of_dic[item2] = (
                                    lst_of_dic[item2],
                                    lst_of_dic[item1],
                                )
                elif sen_or_desen == "降":
                    for item1 in range(len(lst_of_dic) - 1):
                        for item2 in range(item1, len(lst_of_dic)):
                            if int(lst_of_dic[item1][choice]) <= int(
                                lst_of_dic[item2][choice]
                            ):
                                lst_of_dic[item1], lst_of_dic[item2] = (
                                    lst_of_dic[item2],
                                    lst_of_dic[item1],
                                )
                else:
                    print("关键字不存在")
            # 输出排好序的字典到文件

            lst = []
            N = len(lst_of_dic)
            for item in range(N):
                stg = "".join(
                    [
                        "\n",
                        lst_of_dic[item]["学号"],
                        "\t\t",
                        lst_of_dic[item]["姓名"],
                        "\t\t",
                        lst_of_dic[item]["性别"],
                        "\t\t",
                        lst_of_dic[item]["数学"],
                        "\t\t",
                        lst_of_dic[item]["物理"],
                        "\t\t",
                        lst_of_dic[item]["Python"],
                        "\t\t",
                        lst_of_dic[item]["平均成绩"],
                    ]
                )
                lst.append(stg)

            format_title = "{0:^6}\t{1:^6}\t{2:^6}\t{3:^6}\t{4:^6}\t{5:^1}\t{6}"
            print("排序后的结果: ")
            print("学号"," ", "姓名"," ", "性别"," ", "数学"," ","物理", " ","Python"," ","平均分")
            for item in lst_of_dic:

                print(
                    
                        item.get("学号"),"   ",
                        item.get("姓名"),"   ",
                        item.get("性别"),"   ",
                        item.get("数学"),"   ",
                        item.get("物理"),"   ",
                        item.get("Python"),"   ",
                        item.get("平均成绩"),"   "
                    )

            with open("stuinfomgr.txt", "w+", encoding="UTF-8") as fp:
                fp.write(
                    "学号\t\t姓名\t\t性别\t\t数学\t\t物理\t\tPython\t\t平均成绩\n------------------------------------------------------------------------------------"
                )

            # 将修改后的内容写入新文件
            with open("stuinfomgr.txt", "a+", encoding="UTF-8") as fp:
                fp.writelines(lst)

        # 功能模块6：统计学生人数
        elif select == 6:
            # 读取学生信息文件stuinfomgr.txt中的学生信息，统计共有多少人，统计结果用print函数展示
            with open("stuinfomgr.txt", "r", encoding="UTF-8") as fp:
                lst = fp.readlines()

            print("\n共有学生", len(lst) - 2, "人\n")

        # 功能模块7：显示所有学生信息
        elif select == 7:
            try:
                # 读取学生信息文件stuinfomgr.txt中的学生信息，将所有学生的信息格式化地用print展示
                with open("stuinfomgr.txt", "r", encoding="UTF-8") as fp:
                    lst = fp.readlines()

                lst_of_dic = []
                if len(lst) >= 2:
                    for item in lst[2:]:
                        # 使用正则表达式匹配可能的分隔符
                        elem = re.split(r'\t+', item.strip())
                        if len(elem) >= 6:
                            dic = {
                                "学号": elem[0],
                                "姓名": elem[1],
                                "性别": elem[2],
                                "数学": elem[3],
                                "物理": elem[4],
                                "Python": elem[5],
                            }
                            lst_of_dic.append(dic)
                        # else:
                        #     print(f"无效的数据行: {item}")
                else:
                    print("无学生信息，请先录入\n\n")

                # 格式化字符串
                format_title = "{:<6}\t{:<6}\t{:<6}\t{:<6}\t{:<6}\t{:<6}\t{:<6}"

                # ...
                print("学号","  ", "姓名","  ", "性别","  ", "数学", "  ","物理", "  ","Python","  ", "平均分")

                for item in lst_of_dic:
                    stu_ave = (int(item["数学"]) + int(item["物理"]) + int(item["Python"])) / 3
                    stu_ave_str = "{:.2f}".format(stu_ave)
                    print(
                            item.get("学号"),"    ",
                            item.get("姓名"),"    ",
                            item.get("性别"),"    ",
                            item.get("数学"),"    ",
                            item.get("物理"),"    ",
                            item.get("Python"),"    ",
                            stu_ave_str,
                        
                    )
            except FileExistsError:
                print("学生信息文件不存在")

        # 功能模块8：打开学生信息文件stuinfomgr.txt
        elif select == 8:
            path = os.getcwd()
            filename = "stuinfomgr.txt"
            try:
                os.startfile(os.path.join(path, filename))
            except:
                print("学生信息文件不存在")

        # 功能模块9：退出小程序，并删除本程序创建的所有文件（stuinfomgr.txt）和目录（newdir）
        elif select == 9:
            print("\n\n程序已终止\n\n")
            file_path = os.path.join("newdir", "stuinfomgr.txt")

            try:
                # 删除stuinfomgr.txt文件
                os.remove(file_path)
                print(f"文件 {file_path} 已删除")
            except FileNotFoundError:
                print(f"文件 {file_path} 不存在")

            try:
                # 删除newdir目录
                os.rmdir("newdir")
                print("目录 newdir 已删除")
            except FileNotFoundError:
                print("目录 newdir 不存在")

            break
        else:
            print("\n功能不存在,请重新输入\n")


if __name__ == "__main__":
    main()
